﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.IO;

namespace VGSoftware.AutoExtractService
{
	public class Watcher
	{
		private Timer _timer;
		private FileSystemWatcher _fileSystemWatcher;
		private Queue<DirectoryInfo> _filesToProcess = new Queue<DirectoryInfo>();
		private static object _timerLock = new object();
		private static Watcher _instance;
		private static object _instanceLock = new object();

		private Watcher()
		{
		}

		public static Watcher Instance
		{
			get
			{
				if (_instance == null)
				{
					lock (_instanceLock)
					{
						if (_instance == null)
						{
							_instance = new Watcher();
						}
					}
				}
				return _instance;
			}
		}

		public void Start()
		{
			PlugIn.PlugInManager.Instance.Initialize();
			foreach (DirectoryInfo folder in Settings.FoldersToWatch)
			{
				FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(folder.FullName);
				fileSystemWatcher.EnableRaisingEvents = true;
				fileSystemWatcher.IncludeSubdirectories = false;
				fileSystemWatcher.Created += new FileSystemEventHandler(FileSystemWatcher_Created);
			}
			_timer = new Timer();
			_timer.Interval = 1000;
			_timer.AutoReset = true;
			_timer.Enabled = true;
			_timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
		}

		private void Timer_Elapsed(object sender, ElapsedEventArgs e)
		{
			lock (_timerLock)
			{
				if (_filesToProcess.Count > 0 && _filesToProcess.Peek().LastAccessTime.AddSeconds(Properties.Settings.Default.DelayInSeconds) < DateTime.Now)
				{
					RarProcesser.ProcessDirectory(_filesToProcess.Dequeue());
				}
			}			
		}

		public void Stop()
		{
			if (_timer != null)
			{
				_timer.Enabled = false;
			}
			if (_fileSystemWatcher != null)
			{
				_fileSystemWatcher.EnableRaisingEvents = false;
			}
		}

		private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
		{
			DirectoryInfo directory = new DirectoryInfo(e.FullPath);
			if (directory.Exists)
			{
				_filesToProcess.Enqueue(directory);
			}
		}
	}
}
